#==============================================================================
#
#  $Id: tb.py,v 1.2 2001/06/12 00:54:35 mike Exp $
#
"""
   Contains a little bit of custom traceback code to handle preserving
   tracebacks across remote method invocations.
"""
#
#  Copyright (C) 1999 Michael A. Muller
#
#  Permission is granted to use, modify and redistribute this code,
#  providing that the following conditions are met:
#
#  1) This copyright/licensing notice must remain intact.
#  2) If the code is modified and redistributed, the modifications must 
#  include documentation indicating that the code has been modified.
#  3) The author(s) of this code must be indemnified and held harmless
#  against any damage resulting from the use of this code.
#
#  This code comes with ABSOLUTELY NO WARRANTEE, not even the implied 
#  warrantee of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
#
#  $Log: tb.py,v $
#  Revision 1.2  2001/06/12 00:54:35  mike
#  Documentation fixes.
#
#  Revision 1.1  1999/06/14 17:50:15  mike
#  Added the ability to preserve tracebacks across remote method invocations.
#
#
#==============================================================================

import traceback, sys

def errorText(ex):
   """
      Returns a string identical to what would be printed from 
      `traceback.print_exc()`, except that the special "`dopy_traceback`"
      attribute is used (if it exists) to provide traceback detail
      across remote method invocation boundaries.
   """
   info = traceback.extract_tb(sys.exc_traceback)
   
   # add the dopy_traceback if there is one.
   if hasattr(ex, 'dopy_traceback'):
      info = info + ex.dopy_traceback
      
   retval = 'Traceback (innermost last):\n'
   for file, line, func, src in info:
      retval = retval + '  File "' + file + '", line ' + `line` + ', in ' + \
         func + '\n'
      
      # add the source line if there is one
      if src:
         retval = retval + '    ' + src + '\n'
   
   if ex:
      retval = retval + ex.__class__.__name__ + ': ' + str(ex)
   return retval

def saveTraceback(ex):
   """
      Stores traceback information in the exception object under the attribute
      "`dopy_traceback`".
      
      DOPY user code generally need not worry about this function.  It is
      called by the DOPY server prior to passing an exception back through
      a discontinuity.
   """
   info = traceback.extract_tb(sys.exc_traceback)
   
   # if there is already a dopy_traceback attribute, use it.
   if hasattr(ex, 'dopy_traceback'):
      info = info + ex.dopy_traceback

   ex.dopy_traceback = info
      